﻿/*
 * Created by SharpDevelop.
 * User: amb
 * Date: 31/05/2014
 * Time: 12:09
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Linq;

namespace JdFormsDll
{

    public delegate void Save(object sender, DecoratorEventArgs e);
    public delegate void Load(object sender, DecoratorEventArgs e);
        
    public class MyFormDecorator
    {

        public event Save OnSave;
        public event Load OnLoad;

        public string MyFormPath { get; private set; }
        public string MyDllPath { get; private set; }
        public string MyCSharpPath { get; private set; }
        public string MyVbPath { get; private set; }
        public MyForm Form { get; set; }

        private MyFormProperties InitalProperties;

        public MyFormDecorator(MyForm form)
        {
            this.SetPaths(form,Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
        }

        public MyFormDecorator(MyForm form, string path)
        {
            this.SetPaths(form,path);
        }

        private void SetPaths(MyForm form, string path)
        {
            try
            {
            	string mypath=Path.Combine(path, "JdForms.Configurations");
            	DirectoryInfo di = new DirectoryInfo(mypath);
            	if(!di.Exists) di.Create();
            	this.MyFormPath = this.CreateDir(mypath,"Decorator");
            	this.MyDllPath= this.CreateDir(mypath,"Dll");
            	this.MyCSharpPath= this.CreateDir(mypath,"CSharp");
            	this.MyVbPath= this.CreateDir(mypath,"Vb");
                this.InitalProperties = new MyFormProperties(form);
                this.Form = form;
            }
            catch { throw; }
        }
        
        private string CreateDir(string path,string name)
        {
        	string mypath=Path.Combine(path, name);
        	DirectoryInfo di = new DirectoryInfo(mypath);
           	if(!di.Exists) di.Create();
           	return di.FullName;
        }

        public void RestoreProperties()
        {
            this.InitalProperties.SetProperties(this.Form);
        }

        public void OpenDecoratorFolder()
        {
            try
            {
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                prc.StartInfo.FileName = this.MyFormPath;
                prc.Start();
            }
            catch { throw; }
        }
        
        public void OpenDllFolder()
        {
            try
            {
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                prc.StartInfo.FileName = this.MyDllPath;
                prc.Start();
            }
            catch { throw; }
        }
        
        public void OpenCsharpFolder()
        {
            try
            {
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                prc.StartInfo.FileName = this.MyCSharpPath;
                prc.Start();
            }
            catch { throw; }
        }
        
        public void OpenVbFolder()
        {
            try
            {
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                prc.StartInfo.FileName = this.MyVbPath;
                prc.Start();
            }
            catch { throw; }
        }

        public string [] GetFiles()
        {
        	DirectoryInfo di = new DirectoryInfo(this.MyFormPath);
        	FileInfo[] fi = di.GetFiles("*.jdf");
        	return (from FileInfo f in fi select f.FullName).ToArray();
        }
        
        public void Load(string filename)
        {
        	this.LoadDecorator(filename);
        }

        public DialogResult Open()
        {
            DialogResult res = DialogResult.Cancel;
            string filename = string.Empty;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.InitialDirectory = this.MyFormPath;
                ofd.Multiselect = false;
                ofd.CheckFileExists = true;
                ofd.CheckPathExists = true;
                ofd.DefaultExt = "jdf";
                ofd.Filter = "JdForm Decorator files (*.jdf)|*.jdf";
                ofd.FilterIndex = 1;
                ofd.ReadOnlyChecked = true;
                res = ofd.ShowDialog();
                filename = ofd.FileName;
            }
            if (res == DialogResult.OK) this.LoadDecorator(filename);
            return res;
        }


        public DialogResult Save()
        {
            DialogResult res = DialogResult.Cancel;
            string filename = string.Empty;
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.InitialDirectory = this.MyFormPath;
                sfd.CheckFileExists = false;
                sfd.CheckPathExists = true;
                sfd.OverwritePrompt = true;
                sfd.DefaultExt = "jdf";
                sfd.Filter = "JdForm Decorator files (*.jdf)|*.jdf";
                sfd.FilterIndex = 1;
                sfd.FileName = this.Form.Text;
                sfd.SupportMultiDottedExtensions = false;
                res = sfd.ShowDialog();
                filename = sfd.FileName;
            }
            if (res == DialogResult.OK) this.SaveDecorator(filename);
            return res;
        }

        public void CopyTo(MyForm form)
        {
            form.BackColor = this.Form.BackColor;
            form.BackColorShadow = this.Form.BackColorShadow;
            form.BorderColor = this.Form.BorderColor;
            form.TextCaptionColor = this.Form.TextCaptionColor;
            form.TextCaptionColorShadow = this.Form.TextCaptionColorShadow;
            form.ForeColor = this.Form.ForeColor;
            form.BorderStyle = this.Form.BorderStyle;
            form.CaptionBorderRoundPercent = this.Form.CaptionBorderRoundPercent;
            form.ColorsDifferencePercent = this.Form.ColorsDifferencePercent;
            form.TextCaptionAlignment = this.Form.TextCaptionAlignment;
            form.TextCaptionShadow = this.Form.TextCaptionShadow;
            form.IsResizable = this.Form.IsResizable;
            form.IsMoveable = this.Form.IsMoveable;
            form.ShowClientBorder = this.Form.ShowClientBorder;
            form.ShowCaptionBorder = this.Form.ShowCaptionBorder;
            form.ShowTooltip = this.Form.ShowTooltip;
            form.TextCaptionFont = this.Form.TextCaptionFont;
        }

        private void LoadDecorator(string filename)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filename);
                XmlNode root = doc.SelectSingleNode("JdFormDecorator");
                if (root.HasChildNodes)
                {
                    this.Form.BackColor = this.S2C(this.GetNode(root, "BackColor"));
                    this.Form.BackColorShadow = this.S2C(this.GetNode(root, "BackColorShadow"));
                    this.Form.BorderColor = this.S2C(this.GetNode(root, "BorderColor"));
                    this.Form.TextCaptionColor = this.S2C(this.GetNode(root, "TextCaptionColor"));
                    this.Form.TextCaptionColorShadow = this.S2C(this.GetNode(root, "TextCaptionColorShadow"));
                    this.Form.ForeColor = this.S2C(this.GetNode(root, "ForeColor"));
                    this.Form.BorderStyle = this.B3S(this.GetNode(root, "BorderStyle"));
                    this.Form.CaptionBorderRoundPercent = this.P(this.GetNode(root, "CaptionBorderRoundPercent"));
                    this.Form.ColorsDifferencePercent = this.P(this.GetNode(root, "ColorsDifferencePercent"));
                    this.Form.TextCaptionAlignment = this.CA(this.GetNode(root, "TextCaptionAlignment"));
                    this.Form.TextCaptionShadow = this.SW(this.GetNode(root, "TextCaptionShadow"));
                    this.Form.IsResizable = this.B(this.GetNode(root, "IsResizable"));
                    this.Form.IsMoveable = this.B(this.GetNode(root, "IsMoveable"));
                    this.Form.ShowClientBorder = this.B(this.GetNode(root, "ShowClientBorder"));
                    this.Form.ShowCaptionBorder = this.B(this.GetNode(root, "ShowClientBorder"));
                    this.Form.ShowTooltip = this.B(this.GetNode(root, "ShowCaptionBorder"));
                    this.Form.TextCaptionFont = this.S2F(this.GetNode(root, "TextCaptionFont"));
                    root = null;
                    doc = null;
                    if (this.OnLoad != null) this.OnLoad(this, new DecoratorEventArgs(filename));
                }
            }
            catch { throw; }
        }

        private void SaveDecorator(string filename)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                doc.AppendChild(docNode);
                XmlNode root = doc.CreateElement("JdFormDecorator");
                doc.AppendChild(root);
                root.AppendChild(this.SetNode(doc, "BackColor", this.C2S(this.Form.BackColor)));
                root.AppendChild(this.SetNode(doc, "BackColorShadow", this.C2S(this.Form.BackColorShadow)));
                root.AppendChild(this.SetNode(doc, "BorderColor", this.C2S(this.Form.BorderColor)));
                root.AppendChild(this.SetNode(doc, "TextCaptionColor", this.C2S(this.Form.TextCaptionColor)));
                root.AppendChild(this.SetNode(doc, "TextCaptionColorShadow", this.C2S(this.Form.TextCaptionColorShadow)));
                root.AppendChild(this.SetNode(doc, "ForeColor", this.C2S(this.Form.ForeColor)));
                root.AppendChild(this.SetNode(doc, "BorderStyle", Enum.GetName(typeof(Border3DStyle), this.Form.BorderStyle)));
                root.AppendChild(this.SetNode(doc, "CaptionBorderRoundPercent", Enum.GetName(typeof(Percent), this.Form.CaptionBorderRoundPercent)));
                root.AppendChild(this.SetNode(doc, "ColorsDifferencePercent", Enum.GetName(typeof(Percent), this.Form.ColorsDifferencePercent)));
                root.AppendChild(this.SetNode(doc, "TextCaptionAlignment", Enum.GetName(typeof(ContentAlignment), this.Form.TextCaptionAlignment)));
                root.AppendChild(this.SetNode(doc, "TextCaptionShadow", Enum.GetName(typeof(Shadow), this.Form.TextCaptionShadow)));
                root.AppendChild(this.SetNode(doc, "IsResizable", this.Form.IsResizable.ToString()));
                root.AppendChild(this.SetNode(doc, "IsMoveable", this.Form.IsMoveable.ToString()));
                root.AppendChild(this.SetNode(doc, "ShowClientBorder", this.Form.ShowClientBorder.ToString()));
                root.AppendChild(this.SetNode(doc, "ShowCaptionBorder", this.Form.ShowCaptionBorder.ToString()));
                root.AppendChild(this.SetNode(doc, "ShowTooltip", this.Form.ShowTooltip.ToString()));
                root.AppendChild(this.SetNode(doc, "TextCaptionFont", this.F2S(this.Form.TextCaptionFont)));
                doc.Save(filename);
                docNode = null;
                root = null;
                doc = null;
                if (this.OnSave != null) this.OnSave(this, new DecoratorEventArgs(filename));
            }
            catch { throw; }
        }
        
        public bool B(string value)
        {
        	bool result;
        	if(bool.TryParse(value,out result)) return (bool)result;
        	return true;
        }
        
        public Shadow SW(string value)
        {
        	Shadow result;
        	if(Enum.TryParse(value,out result)) return (Shadow)result;
        	return Shadow.None;
        }
        
        public ContentAlignment CA(string value)
        {
        	ContentAlignment result;
        	if(Enum.TryParse(value,out result)) return (ContentAlignment)result;
        	return ContentAlignment.MiddleCenter;
        }
        
        public Percent P(string value)
        {
        	Percent result;
        	if(Enum.TryParse(value, out result)) return (Percent)result;
        	return Percent.Percent0;
        }

        public Border3DStyle B3S(string value)
        {
        	Border3DStyle result;
        	if(Enum.TryParse(value, out result)) return (Border3DStyle)result;
        	return Border3DStyle.Adjust;
        }
        
        public string GetNode(XmlNode node, string name)
        {
            XmlNode n = node.SelectSingleNode(name);
            if(n == null) return string.Empty;
            return n.InnerText;
        }

        private XmlNode SetNode(XmlDocument doc, string name, string value)
        {
            XmlNode node = doc.CreateElement(name);
            node.AppendChild(doc.CreateTextNode(value));
            return node;
        }

        private string F2S(Font f)
        {
            return f.Name + "; " + f.Size.ToString().Replace(",", ".") + "; " + f.Style.ToString();
        }

        public Font S2F(string s)
        {
        	if(string.IsNullOrEmpty(s)) return new Font("Arial",10f,FontStyle.Regular);
            string[] v = s.Split(new string[] { ";" }, StringSplitOptions.None);
            v[1] = v[1].Replace(".", System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
            return new Font(v[0].Trim(), float.Parse(v[1].Trim()), (FontStyle)Enum.Parse(typeof(FontStyle), v[2].Trim()));
        }

        private string C2S(Color c)
        {
            return "#" + c.A.ToString("X2") + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
        }

        public Color S2C(string s)
        {
        	if(string.IsNullOrEmpty(s)) return SystemColors.Control;
            return ColorTranslator.FromHtml(s);
        }

        public DialogResult ShowDialog()
        {
           return this.ShowDialog(null);
        }

        public DialogResult ShowDialog(MyForm parent)
        {
            MyForm oldForm = this.Form;
            DialogResult res = DialogResult.OK;
            using (MyFormEditor frm = new MyFormEditor())
            {
                this.Form = parent;
                frm.Decorator = this;
                frm.StartPosition = FormStartPosition.CenterScreen;
                res = frm.ShowDialog();
            }
            this.Form = oldForm;
            return res;
        }
    }
    
    public class DecoratorEventArgs : EventArgs
    {
    	public DecoratorEventArgs(string filename)
    	{
    		this.FileName=filename;
    	}
    	public string FileName {get;private set;}
    }
}
